package chatClient.view;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.net.*;

//import user created packages
import chatClient.controller.*;
import chat.model.*;


public class ChatClientGUI extends JFrame implements ActionListener, ObserverChatListener, ObservableChatSender{
    private JTextArea messageArea = new JTextArea(15,30); // for the email message body
    private JTextArea responseArea = new JTextArea(15,30); // for the server response etc.
    private JButton sendButton = new JButton("Send");  //use to send the message
    private JButton clearButton = new JButton("Clear Screen");
    private JButton connectButton = new JButton("Connect");
    private JButton disconnectButton = new JButton("Disconnect");
    private JButton helpButton = new JButton("Help");
    private ArrayList <ObserverChatSender> observerList;
    private ChatClientConnection connection;
    private String localHostIpAddress;
    //private static final long serialVersionUID = 1;
    
	//constructor
	public ChatClientGUI(){	
	}
	
	//init the UI
	public void init()
	{
		//init the observerList
		observerList = new ArrayList<ObserverChatSender>();
		
		initUI();		
	}
		
	public void clearAll()
	{
		messageArea.setText("");
		responseArea.setText("");		
	}
	
    public void initUI()
    {
         
    	setSize(600,650);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        InetAddress localHost = null;
    	try
    	{
        	localHost = InetAddress.getLocalHost();
        	localHostIpAddress = localHost.getHostAddress();
    	}
    	catch(Exception ex)
    	{
    		ex.printStackTrace();
    	}
    	
        this.setTitle("HET715 - Group N3 Chat Client v1.0 - " + localHostIpAddress);
              
        Container container = this.getContentPane();
        container.setLayout(new GridBagLayout());      
        GridBagConstraints c = new GridBagConstraints();
        
        Label LResponseArea = new Label("Response Area");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0; // column of the label
        c.gridy = 0; // row of the label
        c.gridwidth = 3; // number of the columns in the component's display area
        c.anchor = GridBagConstraints.PAGE_START;
        container.add(LResponseArea,c);    
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1; // the second row in the first row
        c.gridwidth = 3; // 3 columns wide
        c.gridheight = 4; // 4 rows height
        responseArea.setForeground(Color.blue);
        responseArea.setEditable(false);
        container.add( new JScrollPane(responseArea),c);       
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 4;
        c.gridy = 2;  
        c.insets = new Insets(70,0,0,0);  //top padding
        container.add(clearButton,c);
        clearButton.setToolTipText("Click this button to clear the text boxes");
        clearButton.addActionListener(this);     
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(100,0,0,0);  //top padding
        c.gridx = 4;
        c.gridy = 4;      
        container.add(connectButton,c);
        connectButton.setToolTipText("Click this button to connect to the chat server");
        connectButton.addActionListener(this);
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(130,0,0,0);  //top padding
        c.gridx = 4;
        c.gridy = 4;      
        container.add(disconnectButton,c);
        disconnectButton.setToolTipText("Click this button to disconnect the connection.");
        disconnectButton.addActionListener(this);
       
        
        Label LmessageArea = new Label("Message Area");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(20,0,0,0);  //top padding
        c.gridx = 1;
        c.gridy = 6;
        c.gridwidth = 3;
        c.anchor = GridBagConstraints.CENTER;
        container.add(LmessageArea,c);
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(40,0,0,0);  //top padding
        c.weightx = 2; 
        c.gridx = 0;
        c.gridy = 7;
        c.gridwidth = 3;
        c.gridheight = 4;
        container.add( new JScrollPane(messageArea),c); 
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 4;
        c.gridy = 7;       
        container.add(sendButton,c);
        sendButton.setToolTipText("Click this button to send the messages.");
        sendButton.addActionListener(this); 
        
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(100,0,0,0);  //top padding
        c.weightx = 0.5;
        c.gridx = 4;
        c.gridy = 9;       
        container.add(helpButton,c);
        helpButton.addActionListener(this);
    	
        this.setVisible(true);
    }
    
    public void setConnection(ChatClientConnection theConnection)
    {
    	connection = theConnection;
    }
    
    /**
     * This method is invoked when the send button is pressed
     * @param e button pressed event
     */
    public void actionPerformed(ActionEvent e)
    {
    	System.out.println("button clicked");
    	if (e.getSource() == sendButton )
    	{
        	System.out.println("send button");
    		String message = messageArea.getText();
    		notifyObserverChatSender_SendingMessage(message);
    	}
        else if (e.getSource() == clearButton)
        {
//        	System.out.println("clear button");
        	clearAll();
        }
        else if (e.getSource() == connectButton)
        {
        	connection.connectToServer();
        }
        
        else if (e.getSource() == disconnectButton)
        {
        	connection.disconnectingServer();
        }

    	else if (e.getSource() == helpButton)
    	{
        	   		
    		JFrame help = new displayHelp();
                help.setVisible(true);
    	}
    }
 
    
    //update the response area
    //this method is called by the receiving thread.
	public void updateResponse(String message)
	{
		System.out.println("Textarea receives a message: " + message);
		responseArea.append("\n" + message);
	}

	public void addObserverChatSender(ObserverChatSender observer)
	{
		observerList.add(observer);
	}
		
	//the GUI only need to notify observers when it wants to send messages.
	// it doesn't need to tell observers when it receives message
	public void notifyObserverChatSender_SendingMessage(String message)
	{
		for (ObserverChatSender observer:observerList)
		{
			observer.sendMessage(localHostIpAddress + ": " + message);
		}
	}
}